package rov.ui.view;


import rov.ui.WindowManager;
import rov.data.PreferencesManager;

import java.util.Set;
import java.io.IOException;
import java.io.FileNotFoundException;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;


// GUI for modifying preferences (e.g. joystick mappings, etc.)
public class PreferencesView implements IView
{
    private static final String TITLE = "Preferences";

    private PreferencesManager mPrefs;
    private Container mWindow;
    private JPanel mRoot;
    private JTextField mLeftX;
    private JTextField mLeftY;
    private JTextField mRightX;
    private JTextField mRightY;
    private JTextField mPump;
    private JTextField mCamServo;
    private JButton mApply;
    private JButton mSave;
    private JButton mRevert;


    public String getTitle()
    {
        return TITLE;
    }

    public void create()
    {
        mPrefs = PreferencesManager.getDefaultSimple(false);

        if (mPrefs == null)
        {
            JOptionPane.showMessageDialog(null, "Could not get preferences manager", "Error", JOptionPane.ERROR_MESSAGE);
            return;
        }

     	mWindow = WindowManager.getInstance().createWindow(TITLE, true, true, true, true, 300, 250);
        mRoot = new JPanel();
        mWindow.add(mRoot);

        TitledBorder axisBorder = BorderFactory.createTitledBorder("Joystick Mappings");
        JPanel axis = new JPanel(new GridLayout(2,4));
        axis.setBorder(axisBorder);
        axis.add(new JLabel("Lateral:"));
        axis.add(mLeftX = new JTextField(4));
        axis.add(new JLabel("Right:"));
        axis.add(mRightX = new JTextField(4));
        axis.add(new JLabel("Left:"));
        axis.add(mLeftY = new JTextField(4));
        axis.add(new JLabel("Verticals:"));
        axis.add(mRightY = new JTextField(4));

        JPanel p = new JPanel();
        p.add(new JLabel("Pump Device:"));
        p.add(mPump = new JTextField(4));

        JPanel c = new JPanel();
        c.add(new JLabel("Camera Servo Device:"));
        c.add(mCamServo = new JTextField(4));

        mApply = new JButton("Test");
        mApply.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                applyPrefs();
            }
        });
        mApply.setEnabled(false);

        mSave = new JButton("Save");
        mSave.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                savePrefs();
            }
        });

        mRevert = new JButton("Revert");
        mRevert.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                revertPrefs();
            }
        });

        JButton help = new JButton("Help");
        help.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(null, "This window configures which on-board ROV device receive user input.\nEach text box accepts a comma-separated list of device numbers.\nDevices are numbered starting at 1.\nMotor device numbers should be 1 through 6.\nPump should be device 7, servos: 8, 9, 11, 12, and 13.\nA negative motor device number will reverse its direction.", "Preferences Help", JOptionPane.INFORMATION_MESSAGE);
            }
        });

        JPanel b = new JPanel();
        b.add(mApply);
        b.add(mSave);
        b.add(mRevert);

        mRoot.add(axis);
        mRoot.add(p);
        mRoot.add(c);
        mRoot.add(b);
        mRoot.add(help);

        revertPrefs();
    }

    private void applyPrefs()
    {
    }

    private void savePrefs()
    {
        mPrefs.set(PreferencesManager.LEFT_X_DEV, cleanseList(mLeftX.getText()));
        mPrefs.set(PreferencesManager.LEFT_Y_DEV, cleanseList(mLeftY.getText()));
        mPrefs.set(PreferencesManager.RIGHT_X_DEV, cleanseList(mRightX.getText()));
        mPrefs.set(PreferencesManager.RIGHT_Y_DEV, cleanseList(mRightY.getText()));
        mPrefs.set(PreferencesManager.PUMP_DEV, cleanseList(mPump.getText()));
        mPrefs.set(PreferencesManager.CAMERA_SERVO_DEV, cleanseList(mCamServo.getText()));

        try
        {
            mPrefs.save(PreferencesManager.DEFAULT_PREFS_FILE);
            revertPrefs();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    // re-reads prefs from disk, discards all user changes
    private void revertPrefs()
    {
        try
        {
            mPrefs.load(PreferencesManager.DEFAULT_PREFS_FILE);
        }
        catch (FileNotFoundException e)
        {
            JOptionPane.showMessageDialog(null, "Preferences file doesn't exist:\n\"" +
                                          PreferencesManager.DEFAULT_PREFS_FILE.getAbsolutePath() +
                                          "\"", "Error", JOptionPane.ERROR_MESSAGE);
            return;
        } catch (IOException e)
        {
            e.printStackTrace();
            JOptionPane.showMessageDialog(null, "I/O Error: " + e.getMessage(), "Error",
                                          JOptionPane.ERROR_MESSAGE);
            return;
        }

        mLeftX.setText(toString(mPrefs.getInts(PreferencesManager.LEFT_X_DEV, null)));
        mLeftY.setText(toString(mPrefs.getInts(PreferencesManager.LEFT_Y_DEV, null)));
        mRightX.setText(toString(mPrefs.getInts(PreferencesManager.RIGHT_X_DEV, null)));
        mRightY.setText(toString(mPrefs.getInts(PreferencesManager.RIGHT_Y_DEV, null)));
        mPump.setText(toString(mPrefs.getInts(PreferencesManager.PUMP_DEV, null)));
        mCamServo.setText(toString(mPrefs.getInts(PreferencesManager.CAMERA_SERVO_DEV, null)));
    }

    private String cleanseList(String s) {
        String one = s.replaceAll("[^0-9\\-" + PreferencesManager.VAL_SEPARATOR + "]", "");
        String two = "";

        // remove all occurances of "--"
        while (!one.equals(two))
        {
            two = one;
            one = one.replaceAll("--", "");
        }

        // remove all occurances of ",,"
        while (!one.equals(two))
        {
            two = one;
            one = one.replaceAll(",,", "");
        }

        one = one.replaceAll("-,", "");

        if (one.startsWith(","))
            one = one.substring(1);

        if (one.endsWith("-"))
            one = one.substring(0, one.length() - 1);

        if (one.endsWith(","))
            one = one.substring(0, one.length() - 1);

        return one;
    }

    private String toString(Set<Integer> vals)
    {
        if (vals == null)
            return "";

        StringBuffer sb = new StringBuffer();

        for (Integer v : vals)
        {
            sb.append(v);
            sb.append(PreferencesManager.VAL_SEPARATOR);
        }

        String ret = sb.toString();

        if (ret.isEmpty())
            return ret;
        else
            return ret.substring(0, ret.length() - 1);
    }

    public void destroy()
    {
    }

    public void pause()
    {
    }

    public void resume()
    {
    }
}
